﻿

using HalconDotNet;

namespace DualPlaneFR4Paster.Models
{
    public static class ImageCalc
    {
        public static double[] rotateCenter(double x1, double y1, double x2, double y2, double x3, double y3)
        {
            double a, b, c, d, e, f;
            a = 2 * (x2 - x1);
            b = 2 * (y2 - y1);
            c = x2 * x2 + y2 * y2 - x1 * x1 - y1 * y1;
            d = 2 * (x3 - x2);
            e = 2 * (y3 - y2);
            f = x3 * x3 + y3 * y3 - x2 * x2 - y2 * y2;

            double x = (b * f - e * c) / (b * d - e * a);
            double y = (d * c - a * f) / (b * d - e * a);
            double[] xy = new double[2];
            xy[0] = x;
            xy[1] = y;
            return xy;
        }
        public static void MFindLine(HObject ho_image, out HObject ho_resultRegion, HTuple hv_rowBegin,
      HTuple hv_columnBegin, HTuple hv_rowEnd, HTuple hv_columnEnd, HTuple hv_measureLength1,
      HTuple hv_measureThreshold, HTuple hv_minScore, out HTuple hv_resultRow1, out HTuple hv_resultColumn1,
      out HTuple hv_resultRow2, out HTuple hv_resultColumn2, out HTuple hv_result)
        {
            // Local iconic variables 

            // Local control variables 

            HTuple hv_Width = null, hv_Height = null, hv_MetrologyHandle = null;
            HTuple hv_Index = null, hv_LineParameter = null;
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_resultRegion);
            hv_resultRow1 = new HTuple();
            hv_resultColumn1 = new HTuple();
            hv_resultRow2 = new HTuple();
            hv_resultColumn2 = new HTuple();
            hv_result = new HTuple();

            HOperatorSet.GetImageSize(ho_image, out hv_Width, out hv_Height);
            HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
            HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

            HOperatorSet.AddMetrologyObjectLineMeasure(hv_MetrologyHandle, hv_rowBegin, hv_columnBegin,
                hv_rowEnd, hv_columnEnd, hv_measureLength1, 5, 1, hv_measureThreshold, new HTuple(),
                new HTuple(), out hv_Index);
            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, hv_Index, "num_instances",
                1);
            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, hv_Index, "measure_transition",
                "uniform");
            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, hv_Index, "min_score",
                hv_minScore);
            HOperatorSet.ApplyMetrologyModel(ho_image, hv_MetrologyHandle);

            HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_Index, "all", "result_type",
                "all_param", out hv_LineParameter);
            if ((int)(new HTuple((new HTuple(hv_LineParameter.TupleLength())).TupleEqual(
                4))) != 0)
            {
                hv_result = 1;
                ho_resultRegion.Dispose();
                HOperatorSet.GenRegionLine(out ho_resultRegion, hv_LineParameter.TupleSelect(
                    0), hv_LineParameter.TupleSelect(1), hv_LineParameter.TupleSelect(2), hv_LineParameter.TupleSelect(
                    3));
                hv_resultRow1 = hv_LineParameter.TupleSelect(0);
                hv_resultColumn1 = hv_LineParameter.TupleSelect(1);
                hv_resultRow2 = hv_LineParameter.TupleSelect(2);
                hv_resultColumn2 = hv_LineParameter.TupleSelect(3);
            }
            else
            {
                hv_result = 0;
            }
            HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);

            return;
        }
        public static void FindCircle(HObject image, HTuple hv_Row, HTuple hv_Column, HTuple hv_Radius, HTuple MeasureThrehold,
    out HTuple hv_ResutlRow, out HTuple hv_ResultColumn, out HTuple hv_ResultRadius)
        {
            HTuple hv_MetrologyHandle, hv_Index, hv_CircleParameter;
            HTuple hv_Width = null, hv_Height = null;
            HOperatorSet.GetImageSize(image, out hv_Width, out hv_Height);
            //创建模型
            HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
            HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

            HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_Row, hv_Column,
                hv_Radius, 30, 5, 1, MeasureThrehold, new HTuple(), new HTuple(), out hv_Index);
            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, hv_Index, "num_instances",
                1);
            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, hv_Index, "measure_transition",
                "positive");
            HOperatorSet.SetMetrologyObjectParam(hv_MetrologyHandle, hv_Index, "min_score",
                0.5);
            HOperatorSet.ApplyMetrologyModel(image, hv_MetrologyHandle);

            HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_Index, "all", "result_type",
                "all_param", out hv_CircleParameter);
            HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
            if (hv_CircleParameter.TupleLength() == 3)
            {
                hv_ResutlRow = hv_CircleParameter.TupleSelect(0);
                hv_ResultColumn = hv_CircleParameter.TupleSelect(1);
                hv_ResultRadius = hv_CircleParameter.TupleSelect(2);
            }
            else
            {
                hv_ResutlRow = null;
                hv_ResultColumn = null;
                hv_ResultRadius = null;
            }
        }
        // Procedures 
        public static void MFindAreaCenter(HObject ho_image, out HObject ho_resultRegion, HTuple hv_maxGray,
            HTuple hv_minArea, HTuple hv_maxArea, out HTuple hv_result, out HTuple hv_row,
            out HTuple hv_column)
        {
            // Local iconic variables 

            HObject ho_BlackRegion, ho_RegionClosing, ho_ConnectedRegions;
            HObject ho_RegionFillUp, ho_SelectedRegions;

            // Local control variables 

            HTuple hv_Number = null;
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_resultRegion);
            HOperatorSet.GenEmptyObj(out ho_BlackRegion);
            HOperatorSet.GenEmptyObj(out ho_RegionClosing);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
            HOperatorSet.GenEmptyObj(out ho_RegionFillUp);
            HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
            hv_result = new HTuple();
            hv_row = new HTuple();
            hv_column = new HTuple();
            ho_BlackRegion.Dispose();
            HOperatorSet.Threshold(ho_image, out ho_BlackRegion, 0, hv_maxGray);
            ho_RegionClosing.Dispose();
            HOperatorSet.ClosingCircle(ho_BlackRegion, out ho_RegionClosing, 10);
            ho_ConnectedRegions.Dispose();
            HOperatorSet.Connection(ho_RegionClosing, out ho_ConnectedRegions);
            ho_RegionFillUp.Dispose();
            HOperatorSet.FillUp(ho_ConnectedRegions, out ho_RegionFillUp);
            ho_SelectedRegions.Dispose();
            HOperatorSet.SelectShape(ho_RegionFillUp, out ho_SelectedRegions, "area", "and",
                hv_minArea, hv_maxArea);
            HOperatorSet.CountObj(ho_SelectedRegions, out hv_Number);
            if ((int)(new HTuple(hv_Number.TupleEqual(1))) != 0)
            {
                hv_result = 1;
                ho_resultRegion.Dispose();
                ho_resultRegion = ho_SelectedRegions.CopyObj(1, -1);
                HOperatorSet.RegionFeatures(ho_SelectedRegions, "row", out hv_row);
                HOperatorSet.RegionFeatures(ho_SelectedRegions, "column", out hv_column);
            }
            else
            {
                hv_result = 0;
            }
            ho_BlackRegion.Dispose();
            ho_RegionClosing.Dispose();
            ho_ConnectedRegions.Dispose();
            ho_RegionFillUp.Dispose();
            ho_SelectedRegions.Dispose();

            return;
        }
    }
}
